#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "manager_list.h"
#include "uc_log.h"

void init_manager_list(manager_list_t *freq_list)
{
    // 初始化头尾节点
    freq_list->next = freq_list;
    freq_list->pre = freq_list;
}

int count_manager_list(manager_list_t *freq_list)
{
    // 初始化计数变量
    int count = 0;
    // 初始化操作节点
    manager_list_t *op_node = freq_list->next;

    // 遍历链表，计算节点个数
    while (op_node != freq_list)
    {
        // 计数变量加1
        count++;
        // TRACE_I("count %d op_node  0x%x", count, op_node);
        // 指向下一个节点
        op_node = op_node->next;
    }

    // 返回节点个数
    return count;
}

int count_the_manager_list(manager_list_t *freq_list, void *target, query_element_callback cb)
{
    // 初始化计数器
    int count = 0;
    // 初始化操作节点
    manager_list_t *op_node = freq_list->next;

    // 遍历链表
    while (op_node != freq_list)
    {
        // 调用回调函数，如果返回值为0，则计数器加1
        if (0 == cb(op_node, target))
            count++;
        // TRACE_I("count %d op_node  0x%x", count, op_node);
        // 指向下一个节点
        op_node = op_node->next;
    }

    // 返回计数器
    return count;
}

void insert_head_manager_list(manager_list_t *freq_list, void *data)
{
    // 创建一个节点
    manager_list_t *node = rt_malloc(sizeof(manager_list_t));
    if (RT_NULL == node)
    {
        TRACE_I("%s line %d malloc error", __FUNCTION__, __LINE__);
        return;
    }

    // 初始化节点
    node->data = data;

    // 如果链表为空，则直接将节点插入链表
    if (freq_list->next == freq_list)
    {
        freq_list->next = node;
        freq_list->pre = node;
        node->next = freq_list;
        node->pre = freq_list;
        // TRACE_I("%s line %d node 0x%x, freq_list->next 0x%x", __FUNCTION__, __LINE__, node, freq_list->next);
    }
    else
    {
        // 将节点插入链表头
        node->next = freq_list->next;
        node->pre = freq_list;
        freq_list->next->pre = node;
        freq_list->next = node;
        // TRACE_I("%s line %d", __FUNCTION__, __LINE__);
    }
}

void insert_tail_manager_list(manager_list_t *freq_list, void *data)
{
    // 创建一个节点
    manager_list_t *node = rt_malloc(sizeof(manager_list_t));
    // RT_ASSERT(node);

    // TRACE_I("%s line %d node 0x%x", __FUNCTION__, __LINE__, node);

    // 初始化节点
    node->data = data;

    // 如果链表为空，则直接把节点插入到链表中
    if (freq_list->next == freq_list)
    {
        freq_list->next = node;
        freq_list->pre = node;
        node->next = freq_list;
        node->pre = freq_list;
        // TRACE_I("%s line %d list current is null", __FUNCTION__, __LINE__);
    }
    else
    {
        // 如果链表不为空，则把节点插入到最后一个节点后面
        manager_list_t *old_tail = freq_list->pre;

        // 把最后一个节点的前一个节点指向新节点
        old_tail->next = node;
        node->pre = old_tail;
        // old_tail = node;
        // 把新节点指向第一个节点
        node->next = freq_list;
        freq_list->pre = node;

        // TRACE_I("%s line %d list current no null old_tail 0x%x", __FUNCTION__, __LINE__, old_tail);
    }
}

manager_list_t *get_head_list(manager_list_t *freq_list)
{
    // 获取 freq_list 的下一个节点
    manager_list_t *op_node = freq_list->next;

    // 如果下一个节点不是 freq_list，则返回下一个节点
    if (op_node != freq_list)
        return op_node;

    // 否则，返回空指针
    return RT_NULL;
}

manager_list_t *query_head_list(manager_list_t *freq_list, void *target, query_element_callback cb)
{
    // 遍历freq_list，查找target在freq_list中的位置
    manager_list_t *op_node = freq_list->next;

    while (op_node != freq_list)
    {
        // 如果cb不为空，并且cb函数返回值为0，则返回op_node
        if (RT_NULL != cb && 0 == cb(op_node, target))
            return op_node;
        // 否则，op_node指向下一个节点
        op_node = op_node->next;
    }

    // 如果遍历完freq_list仍未找到，则返回RT_NULL
    return RT_NULL;
}

int remove_head_manager_node(manager_list_t *freq_list, void *parament)
{
    // 遍历频率列表
    manager_list_t *op_node = freq_list->next;

    while (op_node != freq_list)
    {
        // 如果参数节点在原位置
        if (parament == op_node)
        {
            // remove from original position
            // 从原位置移除
            op_node->next->pre = op_node->pre;
            op_node->pre->next = op_node->next;
            // add to head
            // 添加到头部
            insert_head_manager_list(freq_list, op_node->data);
            rt_free(op_node);
            return 0;
        }
        op_node = op_node->next;
    }
    return 1;
}

int del_manager_node(manager_list_t *freq_list, void *parament, del_element_callback cb)
{
    // 定义一个操作节点
    manager_list_t *op_node = freq_list->next;

    // 遍历链表
    while (op_node != freq_list)
    {
        // 如果回调函数返回值为0，则删除该节点
        if (0 == cb(op_node, parament))
        {
            // 删除节点
            op_node->pre->next = op_node->next;
            op_node->next->pre = op_node->pre;
            rt_free(op_node->data);
            rt_free(op_node);
            op_node = RT_NULL;
            return 0;
        }
        // 指向下一个节点
        op_node = op_node->next;
    }
    return 1;
}

int remove_manager_node(manager_list_t *freq_list, void *parament, del_element_callback cb)
{
    // 定义一个操作节点
    manager_list_t *op_node = freq_list->next;

    // 遍历链表
    while (op_node != freq_list)
    {
        // 如果回调函数返回值为0，则删除该节点
        if (0 == cb(op_node, parament))
        {
            // 删除节点
            op_node->pre->next = op_node->next;
            op_node->next->pre = op_node->pre;
            rt_free(op_node);
            op_node = RT_NULL;
            return 0;
        }
        // 指向下一个节点
        op_node = op_node->next;
    }
    // 如果链表遍历结束，说明没有找到要删除的节点，返回1
    return 1;
}

int modify_manager_node(manager_list_t *freq_list, void *parament, modify_element_callback cb)
{
    // 遍历 freq_list 中的每一个节点
    manager_list_t *op_node = freq_list->next;

    while (op_node != freq_list)
    {
        // 如果 cb 不为空，并且 cb 函数的返回值为 0，则返回 0
        if (RT_NULL != cb && 0 == cb(op_node, parament))
            return 0;
        // 否则，继续遍历下一个节点
        op_node = op_node->next;
    }

    // 遍历完毕，返回 1
    return 1;
}

void clean_manager_list(manager_list_t *freq_list)
{
    // 遍历链表
    manager_list_t *op_node = freq_list->next;
    while (op_node != freq_list)
    {
        // 保存下一个节点
        manager_list_t *tmp = op_node;
        // 指向下一个节点
        op_node = op_node->next;
        // 释放节点数据
        rt_free(tmp->data);
        // 释放节点指针
        rt_free(tmp);
        // 释放指针，防止内存泄漏
        tmp = RT_NULL;
    }
    // 重新指向链表头
    freq_list->next = freq_list;
    freq_list->pre = freq_list;
}

void test_head_list(manager_list_t *freq_list, void *target, test_element_callback cb)
{
    // 遍历链表，对每一个节点执行回调函数cb
    manager_list_t *op_node = freq_list->next;
    while (op_node != freq_list)
    {
        cb(op_node, target);
        op_node = op_node->next;
    }
}
